Nachdem der grobe Aufbau einer Freispeicherverwaltung nun klar sein sollte, können wir uns der
Implementierung widmen.
Wie bereits gesagt, brauchen wir irgendeine Art Liste, mit der wir die notwendigen Informationen
abspeichern können.
Dazu gehören einmal die Verzeigerung auf den nächsten freien Speicherblock, sowie die
Information darüber, wie groß dieser Speicherblock ist.
Außerdem, wo er sich befindet.
Dazu können wir zum Beispiel die hier dargestellte M-Block-Struktur verwenden.
Mit dem Eintrag Struktur M-Block Next wird auf den jeweils nächsten Eintrag in der Freispeicherverwaltung
verlinkt, während Zeiss die Größe des durch diesen M-Block referenzierten Speichers angibt,
exklusive des von dem eigenen M-Block belegten Speichers, und der Zeiger Mem Area zeigt auf
den Speicher, der direkt hinter diesem M-Block liegt.
Bei Mem Area handelt es sich dabei um ein Flexible Array Member.
Diese werden so deklariert, dass in den eckigen Klammern keine Größe mit angegeben wird.
Ab diesem Moment kann Mem Area wie ein ganz normales Array verwendet werden, aber es belegt
selber keinen Speicher.
Das heißt, es hat selbst die Größe 0.
Also kann Mem Area dafür verwendet werden, auf genau den Speicher zu verweisen, der hinter
diesem Struktur M-Block liegt.
Bevor wir nun weitermachen mit der Implementierung, noch ein kurzer Einschub zu Zeigern und Zeiger
Arithmetik.
Dafür haben wir hier das Beispiel mit der Struktur Test, die aus zwei Mitgliedern besteht.
Einmal einem 64-Bit Integer Num und einem Zeiger Ptr, von dem wir ausgehen, dass er
8-Bit groß ist.
Das heißt genauso groß wie Num.
Dies könnte zum Beispiel auf einem x86-64-System der Fall sein.
Und für unser Beispiel gehen wir davon aus, dass wir folgende Deklaration haben.
Einmal ein Struktentest-Zeiger namens Arr, der auf das in der rechten Spalte dargestellte
Array verweist.
Das Array hat 7 Felder und besteht aus Struktentest.
Der Zeiger Arr ist dabei initialisiert auf die Adresse des ersten Feldes des Arrays.
Im Folgenden schreiben wir nun einige Zugriffe auf dieses Array und wollen ermitteln, an
welche Stelle die Zugriffe jeweils zeigen.
Damit fangen wir an, indem wir einfach an Arr an Stelle 0 zugreifen und uns davon die
Adresse holen.
Das ist noch relativ einfach.
Damit bekommen wir einfach wieder einen Zeiger, der auf den Anfang des Arrays zeigt.
Wenn wir nun an Stelle 2 des Arrays greifen und uns von dem Objekt mit dem Unteroperator
die Adresse holen, dann bekommen wir nun einen Zeiger, der an den Anfang des dritten Elementes
zeigt bzw. sein Das Element mit dem Indizie 2.
Und nun haben wir einen Ausdruck, bei dem tatsächliche Zeiger-Arithmetik auftritt.
Nämlich rechnen wir nun Arr plus 3.
Und wir erinnern uns, dass bei Zeiger-Arithmetik wir auf der einen Seite einen Zeiger haben,
der mit einem Typ versehen ist, in diesem Fall Arr mit dem Typ Zeigeraufstrukt-Test.
Und auf der anderen Seite zum Beispiel eine Konstante, die wir aufaddieren wollen.
In dem Fall wird nun die Konstante multipliziert mit der Größe des Typs, der durch Arr referenziert
wird.
Das heißt wir rechnen 3 mal die Größe von Strukt-Test, das wäre 3 mal 16.
Und dieser Wert wird auf den Zeigerwert aufaddiert.
Das bedeutet die Speicheradresse plus 3 mal 16.
Zugänglich über
Offener Zugang
Dauer
00:13:43 Min
Aufnahmedatum
2020-05-24
Hochgeladen am
2020-05-24 23:56:35
Sprache
de-DE